Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


meshchatx/src/backend/http/routes/maintenance.py master (b89dc9e6) Text, 14.15 KB

T8b949e# SPDX-License-Identifier: 0BSD
T8b949e"""HTTP routes: maintenance."""

Tff7b72from T7ee787__future__ Tff7b72import Te6edf3annotations


Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787httpT7ee787.T7ee787meshchat_names Tff7b72import Tb4b4b4( T8b949e# noqa: F401
Te6edf3GeoValidationErrorTb4b4b4,
Te6edf3OutboundHttpBlockedErrorTb4b4b4,
Te6edf3OverlayExportErrorTb4b4b4,
Te6edf3OverlaySourceParseErrorTb4b4b4,
Te6edf3PluginSecurityErrorTb4b4b4,
Te6edf3AsyncUtilsTb4b4b4,
Te6edf3InterfaceConfigParserTb4b4b4,
Te6edf3InterfaceDiscoveryTb4b4b4,
Te6edf3InterfaceEditorTb4b4b4,
Te6edf3LOGIN_PATHTb4b4b4,
Te6edf3LXMFTb4b4b4,
Te6edf3LxmfAudioFieldTb4b4b4,
Te6edf3LxmfFileAttachmentTb4b4b4,
Te6edf3LxmfFileAttachmentsFieldTb4b4b4,
Te6edf3LxmfImageFieldTb4b4b4,
Te6edf3MAX_EXPORT_TILESTb4b4b4,
Te6edf3MarkdownRendererTb4b4b4,
Te6edf3NomadnetFileDownloaderTb4b4b4,
Te6edf3NomadnetPageDownloaderTb4b4b4,
Te6edf3RNProbeHandlerTb4b4b4,
Te6edf3RNSTb4b4b4,
Te6edf3ReticulumMeshChatTb4b4b4,
Te6edf3SETUP_PATHTb4b4b4,
Te6edf3TRANSPARENT_TILETb4b4b4,
Te6edf3TelemeterTb4b4b4,
Te6edf3UTCTb4b4b4,
Te6edf3WSMsgTypeTb4b4b4,
Te6edf3_is_chaquopy_androidTb4b4b4,
Te6edf3_is_loopback_bind_hostTb4b4b4,
Te6edf3_request_client_ipTb4b4b4,
Te6edf3aiohttpTb4b4b4,
Te6edf3app_versionTb4b4b4,
Te6edf3assert_migration_context_pathsTb4b4b4,
Te6edf3asyncioTb4b4b4,
Te6edf3base64Tb4b4b4,
Te6edf3bcryptTb4b4b4,
Te6edf3binasciiTb4b4b4,
Te6edf3build_blocklist_export_documentTb4b4b4,
Te6edf3build_export_documentTb4b4b4,
Te6edf3build_messages_export_bundleTb4b4b4,
Te6edf3cache_statsTb4b4b4,
Te6edf3cancel_inbound_deliveriesTb4b4b4,
Te6edf3castTb4b4b4,
Te6edf3compute_lxmf_conversation_unread_from_latest_rowTb4b4b4,
Te6edf3configparserTb4b4b4,
Te6edf3contextlibTb4b4b4,
Te6edf3convert_db_favourite_to_dictTb4b4b4,
Te6edf3convert_db_lxmf_message_to_dictTb4b4b4,
Te6edf3convert_lxmf_message_to_dictTb4b4b4,
Te6edf3convert_nomadnet_field_data_to_mapTb4b4b4,
Te6edf3convert_nomadnet_string_data_to_mapTb4b4b4,
Te6edf3convert_propagation_node_state_to_stringTb4b4b4,
Te6edf3copyTb4b4b4,
Te6edf3datetimeTb4b4b4,
Te6edf3describe_port_conflictTb4b4b4,
Te6edf3detect_image_format_from_magicTb4b4b4,
Te6edf3ensure_outbound_http_allowedTb4b4b4,
Te6edf3ensure_session_csrf_tokenTb4b4b4,
Te6edf3filter_announced_dicts_by_search_queryTb4b4b4,
Te6edf3fresh_storage_at_targetTb4b4b4,
Te6edf3get_cached_active_linkTb4b4b4,
Te6edf3get_file_pathTb4b4b4,
Te6edf3get_sessionTb4b4b4,
Te6edf3get_trusted_proxy_cidrsTb4b4b4,
Te6edf3gif_utilsTb4b4b4,
Te6edf3i2p_supportTb4b4b4,
Te6edf3import_messages_export_bundleTb4b4b4,
Te6edf3ioTb4b4b4,
Te6edf3is_mbtiles_filenameTb4b4b4,
Te6edf3is_path_within_dirTb4b4b4,
Te6edf3is_port_in_useTb4b4b4,
Te6edf3is_user_facing_lxmf_payloadTb4b4b4,
Te6edf3jsonTb4b4b4,
Te6edf3list_host_network_interfacesTb4b4b4,
Te6edf3list_inbound_deliveriesTb4b4b4,
Te6edf3list_portsTb4b4b4,
Te6edf3load_app_security_settingsTb4b4b4,
Te6edf3loggerTb4b4b4,
Te6edf3loggingTb4b4b4,
Te6edf3lxmf_sidebar_preview_for_conversation_latest_rowTb4b4b4,
Te6edf3memory_log_handlerTb4b4b4,
Te6edf3message_fields_have_attachmentsTb4b4b4,
Te6edf3migrate_legacy_to_targetTb4b4b4,
Te6edf3mime_for_image_typeTb4b4b4,
Te6edf3normalize_identity_storage_hashTb4b4b4,
Te6edf3normalize_lxmf_sieve_filtersTb4b4b4,
Te6edf3normalize_message_blocklistTb4b4b4,
Te6edf3osTb4b4b4,
Te6edf3parse_bool_query_paramTb4b4b4,
Te6edf3parse_import_documentTb4b4b4,
Te6edf3parse_lxmf_display_nameTb4b4b4,
Te6edf3parse_lxmf_propagation_node_app_dataTb4b4b4,
Te6edf3parse_lxmf_sieve_filters_jsonTb4b4b4,
Te6edf3parse_lxmf_stamp_costTb4b4b4,
Te6edf3parse_message_blocklist_jsonTb4b4b4,
Te6edf3parse_nomadnetwork_node_display_nameTb4b4b4,
Te6edf3platformTb4b4b4,
Te6edf3privacy_mode_enabledTb4b4b4,
Te6edf3psutilTb4b4b4,
Te6edf3purge_messages_before_cutoffTb4b4b4,
Te6edf3reTb4b4b4,
Te6edf3resolve_message_age_cutoffTb4b4b4,
Te6edf3reticulum_pathfindingTb4b4b4,
Te6edf3rotate_session_csrf_tokenTb4b4b4,
Te6edf3rrc_protocolTb4b4b4,
Te6edf3safe_path_under_dirTb4b4b4,
Te6edf3sanitize_sticker_emojiTb4b4b4,
Te6edf3sanitize_sticker_nameTb4b4b4,
Te6edf3sanitize_websocket_config_updateTb4b4b4,
Te6edf3save_app_security_settingsTb4b4b4,
Te6edf3secretsTb4b4b4,
Te6edf3shutilTb4b4b4,
Te6edf3sqlite3Tb4b4b4,
Te6edf3sticker_pack_utilsTb4b4b4,
Te6edf3sysTb4b4b4,
Te6edf3tempfileTb4b4b4,
Te6edf3threadingTb4b4b4,
Te6edf3timeTb4b4b4,
Te6edf3tracebackTb4b4b4,
Te6edf3user_agent_hashTb4b4b4,
Te6edf3validate_export_documentTb4b4b4,
Te6edf3webTb4b4b4,
Te6edf3websocket_type_requires_authTb4b4b4,
Te6edf3zipfileTb4b4b4,
Tb4b4b4)


Tff7b72def Td2a8ffregister_maintenance_routesTb4b4b4(Te6edf3routesTb4b4b4, Te6edf3appTb4b4b4)Tb4b4b4:

T8b949e# maintenance - clear messages (all, or older than days / before date)
Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/messagesTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_clear_messagesTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3cutoff Tff7b72= Te6edf3resolve_message_age_cutoffTb4b4b4(
Te6edf3older_than_daysTff7b72=Te6edf3requestTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffolder_than_daysTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3beforeTff7b72=Te6edf3requestTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffbeforeTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72if Te6edf3cutoff Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffdelete_all_lxmf_messagesTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffAll messages clearedTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffdeletedTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4}
Tb4b4b4)

Tff7b72def Td2a8ff_cancelTb4b4b4(Te6edf3hTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3appTff7b72.Td2a8ffmessage_router Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3appTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffcancel_outboundTb4b4b4(Te6edf3hTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass

Te6edf3deleted Tff7b72= Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffto_threadTb4b4b4(
Te6edf3purge_messages_before_cutoffTb4b4b4,
Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmessagesTb4b4b4,
Te6edf3_cancelTb4b4b4,
Te6edf3cutoffTb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff"Ta5d6ffDeleted Tffd700{Te6edf3deletedTffd700}Ta5d6ff messages older than cutoffTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdeletedTa5d6ff"Tb4b4b4: Te6edf3deletedTb4b4b4,
Ta5d6ff"Ta5d6ffcutoffTa5d6ff"Tb4b4b4: Te6edf3cutoffTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/messages/duplicatesTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_messages_duplicates_previewTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3count Tff7b72= Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffto_threadTb4b4b4(
Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffcount_duplicate_lxmf_messages_by_contentTb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffcountTa5d6ff"Tb4b4b4: Te6edf3countTb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/messages/duplicatesTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_messages_duplicates_clearTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ff_clearTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3hashes Tff7b72= Tb4b4b4(
Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmessagesTff7b72.Td2a8fflist_duplicate_lxmf_message_hashes_by_contentTb4b4b4(Tb4b4b4)
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3hashesTb4b4b4:
Tff7b72return T79c0ff0
Tff7b72if Te6edf3appTff7b72.Td2a8ffmessage_router Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Tff7b72for Te6edf3h Tff7b72in Te6edf3hashesTb4b4b4:
Tff7b72if Tff7b72not Te6edf3h Tff7b72or Tffa657lenTb4b4b4(Te6edf3hTb4b4b4) Tff7b72% T79c0ff2 Tff7b72!= T79c0ff0Tb4b4b4:
Tff7b72continue
Tff7b72tryTb4b4b4:
Te6edf3appTff7b72.Td2a8ffmessage_routerTff7b72.Td2a8ffcancel_outboundTb4b4b4(Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3hTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass
Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffdelete_lxmf_messages_by_hashesTb4b4b4(Te6edf3hashesTb4b4b4)
Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffprune_conversation_metadata_for_peers_with_no_messagesTb4b4b4(Tb4b4b4)
Tff7b72return Tffa657lenTb4b4b4(Te6edf3hashesTb4b4b4)

Te6edf3deleted Tff7b72= Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffto_threadTb4b4b4(Te6edf3_clearTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff"Ta5d6ffDeleted Tffd700{Te6edf3deletedTffd700}Ta5d6ff duplicate messagesTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdeletedTa5d6ff"Tb4b4b4: Te6edf3deletedTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/messages/purge-previewTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_messages_purge_previewTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3cutoff Tff7b72= Te6edf3resolve_message_age_cutoffTb4b4b4(
Te6edf3older_than_daysTff7b72=Te6edf3requestTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffolder_than_daysTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3beforeTff7b72=Te6edf3requestTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffbeforeTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Tff7b72if Te6edf3cutoff Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffolder_than_days or before is requiredTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Te6edf3count Tff7b72= Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffcount_lxmf_messages_with_timestamp_beforeTb4b4b4(
Te6edf3cutoffTb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffcountTa5d6ff"Tb4b4b4: Te6edf3countTb4b4b4, Ta5d6ff"Ta5d6ffcutoffTa5d6ff"Tb4b4b4: Te6edf3cutoffTb4b4b4}Tb4b4b4)

T8b949e# maintenance - clear announces

T8b949e# maintenance - clear announces
Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/announcesTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_clear_announcesTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3aspect Tff7b72= Te6edf3requestTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaspectTa5d6ff"Tb4b4b4)
Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffannouncesTff7b72.Td2a8ffdelete_all_announcesTb4b4b4(Te6edf3aspectTff7b72=Te6edf3aspectTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff"Ta5d6ffAnnounces clearedTffd700{Ta5d6ff'Ta5d6ff for aspect Ta5d6ff' Tff7b72+ Te6edf3aspect Tff7b72if Te6edf3aspect Tff7b72else Ta5d6ff'Ta5d6ff'Tffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

T8b949e# maintenance - clear favorites

T8b949e# maintenance - clear favorites
Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/favouritesTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_clear_favouritesTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3aspect Tff7b72= Te6edf3requestTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffaspectTa5d6ff"Tb4b4b4)
Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffannouncesTff7b72.Td2a8ffdelete_all_favouritesTb4b4b4(Te6edf3aspectTff7b72=Te6edf3aspectTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff"Ta5d6ffFavourites clearedTffd700{Ta5d6ff'Ta5d6ff for aspect Ta5d6ff' Tff7b72+ Te6edf3aspect Tff7b72if Te6edf3aspect Tff7b72else Ta5d6ff'Ta5d6ff'Tffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

T8b949e# maintenance - clear archives

T8b949e# maintenance - clear archives
Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/archivesTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_clear_archivesTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmiscTff7b72.Td2a8ffdelete_archived_pagesTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffAll archived pages clearedTa5d6ff"Tb4b4b4}Tb4b4b4)

T8b949e# maintenance - clear LXMF icons

T8b949e# maintenance - clear LXMF icons
Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/lxmf-iconsTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_clear_lxmf_iconsTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmiscTff7b72.Td2a8ffdelete_all_user_iconsTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffAll LXMF icons clearedTa5d6ff"Tb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/stickersTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_clear_stickersTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3n Tff7b72= Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffstickersTff7b72.Td2a8ffdelete_all_for_identityTb4b4b4(Te6edf3identity_hashTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffStickers clearedTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffdeletedTa5d6ff"Tb4b4b4: Te6edf3nTb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/gifsTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_clear_gifsTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Te6edf3identity_hash Tff7b72= Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3n Tff7b72= Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffgifsTff7b72.Td2a8ffdelete_all_for_identityTb4b4b4(Te6edf3identity_hashTb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffGIFs clearedTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffdeletedTa5d6ff"Tb4b4b4: Te6edf3nTb4b4b4}Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffdeleteTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/path-tableTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_clear_path_tableTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3dropped Tff7b72= Te6edf3appTff7b72.Td2a8ffrnpath_handlerTff7b72.Td2a8ffdrop_all_pathsTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffPath table clearedTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffdroppedTa5d6ff"Tb4b4b4: Te6edf3droppedTb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff500Tb4b4b4)

T8b949e# maintenance - export messages (optional age filter for archive-before-purge)

T8b949e# maintenance - export messages (optional age filter for archive-before-purge)
Tf0883e@routesTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/messages/exportTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_export_messagesTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3cutoff Tff7b72= Te6edf3resolve_message_age_cutoffTb4b4b4(
Te6edf3older_than_daysTff7b72=Te6edf3requestTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffolder_than_daysTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3beforeTff7b72=Te6edf3requestTff7b72.Td2a8ffqueryTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffbeforeTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149ValueError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)
Te6edf3messages_list Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3page_size Tff7b72= T79c0ff5000
Te6edf3offset Tff7b72= T79c0ff0
Tff7b72while Tff7b72TrueTb4b4b4:
Tff7b72if Te6edf3cutoff Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3page Tff7b72= Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffget_all_lxmf_messagesTb4b4b4(
Te6edf3limitTff7b72=Te6edf3page_sizeTb4b4b4,
Te6edf3offsetTff7b72=Te6edf3offsetTb4b4b4,
Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3page Tff7b72= Te6edf3appTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffget_lxmf_messages_with_timestamp_beforeTb4b4b4(
Te6edf3cutoffTb4b4b4,
Te6edf3limitTff7b72=Te6edf3page_sizeTb4b4b4,
Te6edf3offsetTff7b72=Te6edf3offsetTb4b4b4,
Tb4b4b4)
Te6edf3messages_listTff7b72.Td2a8ffextendTb4b4b4(Tffa657dictTb4b4b4(Te6edf3mTb4b4b4) Tff7b72for Te6edf3m Tff7b72in Te6edf3pageTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3pageTb4b4b4) Tff7b72< Te6edf3page_sizeTb4b4b4:
Tff7b72break
Te6edf3offset Tff7b72+Tff7b72= Te6edf3page_size
Te6edf3bundle Tff7b72= Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffto_threadTb4b4b4(
Te6edf3build_messages_export_bundleTb4b4b4,
Te6edf3appTff7b72.Td2a8ffdatabaseTb4b4b4,
Te6edf3messages_listTb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3bundleTb4b4b4)

Tff7b72def Td2a8ff_message_import_responseTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3resultTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffokTa5d6ff"Tb4b4b4, Tff7b72TrueTb4b4b4) Tff7b72and Te6edf3resultTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffimportedTa5d6ff"Tb4b4b4: Te6edf3resultTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffimportedTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffskippedTa5d6ff"Tb4b4b4: Te6edf3resultTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffskippedTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Te6edf3imported Tff7b72= Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6ffimportedTa5d6ff"Tb4b4b4]
Te6edf3skipped Tff7b72= Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6ffskippedTa5d6ff"Tb4b4b4]
Te6edf3errors Tff7b72= Te6edf3resultTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fferrorsTa5d6ff"Tb4b4b4) Tff7b72or Tb4b4b4[Tb4b4b4]
Tff7b72if Te6edf3imported Tff7b72== T79c0ff0 Tff7b72and Te6edf3errorsTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Te6edf3errorsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffimportedTa5d6ff"Tb4b4b4: Te6edf3importedTb4b4b4,
Ta5d6ff"Ta5d6ffskippedTa5d6ff"Tb4b4b4: Te6edf3skippedTb4b4b4,
Ta5d6ff"Ta5d6fferrorsTa5d6ff"Tb4b4b4: Te6edf3errorsTb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)
Te6edf3response Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff"Ta5d6ffSuccessfully imported Tffd700{Te6edf3importedTffd700}Ta5d6ff messagesTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffimportedTa5d6ff"Tb4b4b4: Te6edf3importedTb4b4b4,
Ta5d6ff"Ta5d6ffskippedTa5d6ff"Tb4b4b4: Te6edf3skippedTb4b4b4,
Ta5d6ff"Ta5d6ffcontacts_addedTa5d6ff"Tb4b4b4: Te6edf3resultTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcontacts_addedTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffcontacts_skippedTa5d6ff"Tb4b4b4: Te6edf3resultTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffcontacts_skippedTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffdisplay_names_importedTa5d6ff"Tb4b4b4: Te6edf3resultTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffdisplay_names_importedTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffread_state_importedTa5d6ff"Tb4b4b4: Te6edf3resultTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffread_state_importedTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4,
Tb4b4b4}
Tff7b72if Te6edf3errorsTb4b4b4:
Te6edf3responseTb4b4b4[Ta5d6ff"Ta5d6fferrorsTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3errors
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Te6edf3responseTb4b4b4)

T8b949e# maintenance - import messages

T8b949e# maintenance - import messages
Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/messages/importTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_import_messagesTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3data Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3appTff7b72.Td2a8ffdatabase Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffNo active identity databaseTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)

Te6edf3result Tff7b72= Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffto_threadTb4b4b4(
Te6edf3import_messages_export_bundleTb4b4b4,
Te6edf3appTff7b72.Td2a8ffdatabaseTb4b4b4,
Te6edf3dataTb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3_message_import_responseTb4b4b4(Te6edf3resultTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)

Tf0883e@routesTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/maintenance/messages/import-fileTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffmaintenance_import_messages_fileTb4b4b4(Te6edf3requestTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3appTff7b72.Td2a8ffdatabase Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffNo active identity databaseTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)

Te6edf3reader Tff7b72= Tff7b72await Te6edf3requestTff7b72.Td2a8ffmultipartTb4b4b4(Tb4b4b4)
Te6edf3field Tff7b72= Tff7b72await Te6edf3readerTff7b72.Td2a8ffnextTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3field Tff7b72is Tff7b72None Tff7b72or Te6edf3fieldTff7b72.Td2a8ffname Tff7b72!= Ta5d6ff"Ta5d6fffileTa5d6ff"Tb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffImport file is requiredTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)

Te6edf3chunks Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72while Tff7b72TrueTb4b4b4:
Te6edf3chunk Tff7b72= Tff7b72await Te6edf3fieldTff7b72.Td2a8ffread_chunkTb4b4b4(Te6edf3sizeTff7b72=T79c0ff1024 Tff7b72* T79c0ff1024Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3chunkTb4b4b4:
Tff7b72break
Te6edf3chunksTff7b72.Td2a8ffappendTb4b4b4(Te6edf3chunkTb4b4b4)
Te6edf3raw Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ff"Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3chunksTb4b4b4)

Tff7b72tryTb4b4b4:
Te6edf3payload Tff7b72= Te6edf3jsonTff7b72.Td2a8ffloadsTb4b4b4(Te6edf3rawTb4b4b4)
Tff7b72except Te6edf3jsonTff7b72.Td2a8ffJSONDecodeError Tff7b72as Te6edf3excTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff"Ta5d6ffInvalid JSON: Tffd700{Te6edf3excTffd700}Ta5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3statusTff7b72=T79c0ff400Tb4b4b4,
Tb4b4b4)

Te6edf3result Tff7b72= Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffto_threadTb4b4b4(
Te6edf3import_messages_export_bundleTb4b4b4,
Te6edf3appTff7b72.Td2a8ffdatabaseTb4b4b4,
Te6edf3payloadTb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3_message_import_responseTb4b4b4(Te6edf3resultTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72return Te6edf3webTff7b72.Td2a8ffjson_responseTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fferrorTa5d6ff"Tb4b4b4: Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4}Tb4b4b4, Te6edf3statusTff7b72=T79c0ff400Tb4b4b4)

T8b949e# get config


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────